//
//  UIViewController+MFAPMCrashMonitor.m
//  AvoidCrash
//
//  Created by zhang liyu on 2019/5/27.
//

#import "UIViewController+MFAPMCrashMonitor.h"

#import "MFAPMCrashMonitorModel.h"
#import "NSObject+MFAPMSwizzle.h"
#import "MFAPMUploadManager.h"
#import "MFAPMUtility.h"
#import <objc/runtime.h>

const char kMFAPMCrashMonitorVCLeaksCheckKey;
@implementation UIViewController (MFAPMCrashMonitor)

#pragma mark - Initial Actions

+ (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [[self class] mfapm_swizzleInstanceSEL:@selector(viewWillAppear:) toSEL:@selector(mfapm_viewWillAppear:)];
        [[self class] mfapm_swizzleInstanceSEL:@selector(viewDidDisappear:) toSEL:@selector(mfapm_viewDidDisappear:)];
    });
}

#pragma mark - Exchange Handle Actions

- (void)mfapm_viewWillAppear:(BOOL)animated{
    [self mfapm_viewWillAppear:animated];
    [self setIsLeak:NO];
}

- (void)mfapm_viewDidDisappear:(BOOL)animated{
    [self mfapm_viewDidDisappear:animated];
    if(self.isLeak){
        [self mfapm_willDealloc];
    }
}

- (void)mfapm_willDealloc{
    __weak typeof(&*self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf mfapm_VCNotDealloc];
    });
}

- (void)mfapm_VCNotDealloc{
    
    MFAPMCrashMonitorModel *leaksModel = [[MFAPMCrashMonitorModel alloc] init];
    leaksModel.leakVCName = NSStringFromClass(self.class) ? : @"";
    leaksModel.leakFuncName = [NSString stringWithCString:(__func__) encoding:NSUTF8StringEncoding];
    leaksModel.stack = [MFAPMUtility callerStackStr];
    [leaksModel configExtend];
    
    //进行数据的保存及后续的上传操作
    [MFAPMUploadManager cacheItem:leaksModel];
}

#pragma mark - Setter & Getter

- (void)setIsLeak:(BOOL)isLeak{
    objc_setAssociatedObject(self, &kMFAPMCrashMonitorVCLeaksCheckKey, @(isLeak), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)isLeak{
    return [objc_getAssociatedObject(self, &kMFAPMCrashMonitorVCLeaksCheckKey) boolValue];
}

@end
